<!-- eslint-disable -->
<template>
  <view style="position: relative; width: 100%; height: 100%; overflow: hidden">
    <view
      v-html="videoHtml"
      class="app-dom-video-vessel"
      style="position: relative; width: 100%; height: 100%; overflow: hidden"
      :props="videoProps"
      :change:props="domVideo.propsChange"
      :videoEventInfo="videoEventInfo"
      :change:videoEventInfo="domVideo.videoEventInfoChange"
      hover-class="none"
      @click="handlerClick"
    ></view>
    <!-- 播放暂停 -->
    <view
      class="play-button"
      :style="{ opacity: showMask ? 1 : 0, transform: `translate(-50%, -50%) scale(${showMask ? 1 : 0})` }"
      @click.stop.prevent="playClick"
    >
      <image :src="playStatus !== 'play' ? `/static/images/video/ico_play.svg` : '/static/images/video/ico_pause.svg'" style="width: 24px; height: 24px" />
    </view>
    <!-- 加载中 -->
    <view v-if="loading" class="square-box">
      <view class="square">
        <view class="bar bar1"></view>
        <view class="bar bar2"></view>
        <view class="bar bar3"></view>
        <view class="bar bar4"></view>
        <view class="bar bar5"></view>
        <view class="bar bar6"></view>
        <view class="bar bar7"></view>
        <view class="bar bar8"></view>
        <view class="bar bar9"></view>
        <view class="bar bar10"></view>
        <view class="bar bar11"></view>
        <view class="bar bar12"></view>
      </view>
    </view>

    <!-- 底部进度 -->
    <view
      class="action-vessel"
      :style="{
        height: `${actionHeight + safeAreaInsetsBottom}px`,
        paddingBottom: `${safeAreaInsetsBottom}px`,
        transform: `translateY(${showMask ? 0 : actionHeight + safeAreaInsetsBottom}px)`,
      }"
    >
      <view class="action-box" :style="{ height: `${actionHeight}px` }">
        <view class="time-box">
          <text class="time">{{ currTime }}</text>
        </view>
        <view class="slider-box">
          <slider
            class="slider"
            :value="sliderValue"
            backgroundColor="#999999"
            activeColor="#ffffff"
            :blockSize="14"
            @change="sliderChange"
            @changing="sliderChanging"
            :min="0"
            :max="duration"
          />
        </view>
        <view class="time-box">
          <text class="time">{{ endTime }}</text>
        </view>
      </view>
    </view>
  </view>
</template>

<script>
  import { getOnlyID } from '@/mxp-ui/mxp-tool/utils/common';
  import { formatMinuteSecond } from '@/mxp-ui/mxp-tool/utils/time';
  export default {
    name: 'app-video',
    expose: ['play', 'pause', 'stop', 'seek', 'requestFullScreen', 'exitFullScreen'],

    props: {
      /** id */
      id: { type: String, default: '' },
      /** 视频链接 */
      src: { type: String, default: '' },
      /** 视频链接 */
      autoplay: { type: Boolean, default: false },
      /** 是否循环播放 */
      loop: { type: Boolean, default: false },
      /** 视频裁剪方式 */
      objectFit: { type: String, default: 'cover' },
      /** 是否静音播放 */
      muted: { type: Boolean, default: false },
      /** 海报 */
      poster: { type: String, default: '' },
      /** 底部安全距离 */
      safeAreaInsetsBottom: { type: Number, default: 0 },
    },

    // 数据状态
    data() {
      const id = this.id || getOnlyID('mxp-video');
      return {
        /** ID */
        onlyID: id,
        /** 播放状态 */
        playStatus: this.autoplay ? 'play' : 'pause',
        /** 用于通知renderjs设置播放和暂停状态 */
        videoEventInfo: { status: '', seek: 0 },
        /** 滑块的值 */
        sliderValue: 0,
        /** 视频总时长 */
        duration: 100,
        /** 是否正在滑动 */
        isSlider: false,
        /** 是否正在加载中 */
        loading: false,
        /** 视频当前播放时间 */
        currTime: '00:00',
        /** 视频总时长 */
        endTime: '00:00',
        showMask: false,
        /** 用于延迟关闭Mask */
        showMaskTimeout: null,
        /** 底部控制条的高度 */
        actionHeight: 40,
        /** 用于延迟显示加载中的动画 */
        timeout: null,
        videoHtml: `<video
                src="${this.src || ' '}"
                id="${id}"
                class="dom-html-video"
                ${this.autoplay ? 'autoplay' : ''}
                ${this.loop ? 'loop' : ''}
                ${this.muted ? 'muted' : ''}
                ${this.poster ? `poster="${this.poster}"` : ''}
                preload="auto"
                x5-video-player-type="h5"
                webkit-playsinline="true"
                playsinline="true"
                x5-playsinline
                t7-video-player-type="inline"
                x-webkit-airplay="allow"
                width="100%"
                height="100%"
                style="object-fit: ${this.objectFit};padding:0;position:relative;"
              >
              </video>
              <div
                id="${id}__progress_mask"
                style="
                  position: absolute;
                  inset: 0;
                  z-index: 2;
                  display: none;
                  flex-direction: column;
                  align-items: center;
                  justify-content: center;
                  width: 100%;
                  height: 100%;
                  margin: 0;
                  background: rgba(0, 0, 0, 0.2);
                "
              >
                <div class="progress-box" style="display: flex; align-items: flex-end; justify-content: center">
                  <span class="curr-time" style="font-size: 22px; line-height:1em; color: #3450d1">00:00</span>
                  <span style="font-size: 18px; color: #ffffff;margin:0 4px; line-height:1em; ">/</span>
                  <span class="total-time" style="font-size: 18px; color: #ffffff; line-height:1em; ">00:00</span>
                </div>
                <div class="progress-bg" style="width: 200px; height: 4px; margin-top: 10px; overflow: hidden; background: rgba(220,220,220,0.5);-webkit-backdrop-filter: blur(6px);backdrop-filter: blur(6px); border-radius: 6px">
                  <div class="progress" style="width: 200px; height:4px; background: #3450d1"></div>
                </div>
              </div>
            `,
      };
    },

    computed: {
      videoProps() {
        return {
          src: this.src,
          autoplay: this.autoplay,
          loop: this.loop,
          objectFit: this.objectFit,
          muted: this.muted,
          poster: this.poster,
          onlyID: this.onlyID,
        };
      },
    },

    watch: {
      showMask(val) {
        // eslint-disable-next-line vue/require-explicit-emits
        this.$emit('maskChange', { show: val, buttonBarHeight: val ? this.actionHeight + this.safeAreaInsetsBottom : 0 });
      },
    },

    beforeUnmount() {
      clearTimeout(this.timeout);
    },

    methods: {
      /** 点击事件 */
      handlerClick() {
        this.showMask = !this.showMask;
        this.hideMask();
      },

      hideMask() {
        clearTimeout(this.showMaskTimeout);
        if (this.showMask) {
          this.showMaskTimeout = setTimeout(() => {
            this.showMask = false;
          }, 4000);
        }
      },

      /** 滚动 */
      sliderChange(event) {
        this.isSlider = false;
        this.sliderValue = event.detail.value;
        this.videoEventInfo = { status: 'seek', seek: event.detail.value };
        this.hideMask();
      },

      sliderChanging() {
        this.isSlider = true;
        this.hideMask();
        // this.sliderValue = event.detail.value;
        // this.videoEventInfo = { status: 'seek', seek: event.detail.value };
      },

      playClick() {
        if (this.showMask) {
          this.playStatus === 'play' ? this.pause() : this.play();
        }
      },

      // 将video的事件传递给父组件
      // eslint-disable-next-line vue/no-unused-properties
      videoEvent(data) {
        if (data.type === 'pause') {
          this.playStatus = 'pause';
        } else if (data.type === 'play') {
          this.playStatus = 'play';
        } else if (data.type === 'duration') {
          this.duration = data.duration;
          this.endTime = formatMinuteSecond(data.duration);
        } else if (data.type === 'seek') {
          if (!this.isSlider) {
            this.sliderValue = data.seek;
            this.currTime = formatMinuteSecond(data.seek);
          }
        }
        if (data.type === 'loadstart') {
          clearTimeout(this.timeout);
          this.timeout = setTimeout(() => {
            // 延迟为了体验好延迟1秒显示
            this.loading = true;
          }, 1000);
        }
        if (data.type === 'error') {
          clearTimeout(this.timeout);
          this.loading = false;
        }
        if (data.type === 'loadedmetadata') {
          clearTimeout(this.timeout);
          this.loading = false;
        }
        this.$emit(data.type, { ...data });
      },

      play() {
        this.videoEventInfo = { status: 'play' };
      },

      pause() {
        this.videoEventInfo = { status: 'pause' };
      },

      stop() {
        this.videoEventInfo = { status: 'stop' };
      },

      seek(num) {
        this.videoEventInfo = { status: 'seek', seek: num };
      },

      requestFullScreen() {
        this.videoEventInfo = { status: 'requestFullScreen', seek: num };
      },

      exitFullScreen() {
        this.videoEventInfo = { status: 'exitFullScreen', seek: num };
      },
    },
  };
</script>

<script module="domVideo" lang="renderjs" src="./renderjs.js"></script>

<style lang="scss" scoped>
  /** 加载动画 **/
  @keyframes load {
    0% {
      opacity: 0;
    }

    100% {
      opacity: 1;
    }
  }

  /** 加载动画 **/
  @keyframes load {
    0% {
      opacity: 0.1;
    }

    100% {
      opacity: 1;
    }
  }

  .dom-video {
    display: block;
    height: 100%;
    padding: 0;
    overflow: hidden;
  }

  .play-button {
    position: fixed;
    inset: 0;
    top: 50%;
    left: 50%;
    z-index: 999;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 56px;
    height: 56px;
    background: rgba(0, 0, 0, 0.5);
    border-radius: 50%;
    transition-timing-function: ease-in-out;
    transition-duration: 0.3s;
    transition-property: transform, opacity;
    transform: translate(-50%, -50%) scale(0);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
  }

  .action-vessel {
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 2;
    box-sizing: border-box;
    width: 100%;
    background: rgba(0, 0, 0, 0.5);
    transition-timing-function: ease-in-out;
    transition-duration: 0.3s;
    transition-property: transform, opacity;

    .action-box {
      box-sizing: border-box;
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 30px;
      padding: 0 15px;
      overflow: hidden;

      .time-box {
        display: flex;
        justify-content: center;
        width: 36px;

        .time {
          font-size: 12px;
          line-height: 12px;
          color: #ffffff;
        }
      }

      .slider-box {
        box-sizing: border-box;
        flex: 1;
        padding: 0 10px;

        .slider {
          width: 100%;
          margin-right: 0;
          margin-left: 0;
        }
      }
    }
  }

  .square-box {
    --bar-width: 3px;
    --size: 36px;
    --diameter: 6px;
    position: fixed;
    inset: 0;
    top: 50%;
    left: 50%;
    z-index: 999;
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--size);
    height: var(--size);
    border-radius: 50%;
    transition-timing-function: ease-in-out;
    transition-duration: 0.3s;
    transition-property: transform, opacity;
    transform: translate(-50%, -50%);
  }

  .square {
    --square-size: calc(var(--size) - var(--diameter) * 2);
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    width: var(--square-size);
    height: var(--square-size);
    border-radius: 50%;
  }

  .bar {
    position: absolute;
    top: 50%;
    left: 50%;
    width: var(--bar-width);
    height: calc(var(--square-size) / 2);
    margin-top: calc(var(--square-size) / 2 * -1);
    margin-left: calc(var(--bar-width) / 2 * -1);
    background: #ffffff;
    border-radius: 999px;
    transform-origin: bottom center;

    &.bar1 {
      opacity: 1;
      transform: rotate(0deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0s infinite;
    }

    &.bar2 {
      opacity: 0.93;
      transform: rotate(30deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.05s infinite;
    }

    &.bar3 {
      opacity: 0.86;
      transform: rotate(60deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.1s infinite;
    }

    &.bar4 {
      opacity: 0.79;
      transform: rotate(90deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.15s infinite;
    }

    &.bar5 {
      opacity: 0.72;
      transform: rotate(120deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.2s infinite;
    }

    &.bar6 {
      opacity: 0.65;
      transform: rotate(150deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.25s infinite;
    }

    &.bar7 {
      opacity: 0.58;
      transform: rotate(180deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.3s infinite;
    }

    &.bar8 {
      opacity: 0.51;
      transform: rotate(210deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.35s infinite;
    }

    &.bar9 {
      opacity: 0.44;
      transform: rotate(240deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.4s infinite;
    }

    &.bar10 {
      opacity: 0.37;
      transform: rotate(270deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.45s infinite;
    }

    &.bar11 {
      opacity: 0.3;
      transform: rotate(300deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.5s infinite;
    }

    &.bar12 {
      opacity: 0.23;
      transform: rotate(330deg) translate(0%, calc(var(--diameter) * -1));
      animation: load 0.6s linear 0.55s infinite;
    }
  }
</style>
